#pragma once

#include <sys/epoll.h>

#include "Common.hpp"
#include "log.hpp"
class epoller
{
    const static int gsize = 128;

private:
    bool handlerFdEvent(int fd, uint32_t event, int type)
    {
        epoll_event ev;
        ev.events = event;
        ev.data.fd = fd;
        int n = epoll_ctl(_epfd, type, fd, &ev);
        if (n < 0)
        {
            return false;
        }
        return true;
    }

public:
    epoller()
    {
        _epfd = epoll_create(gsize);
        if (_epfd < 0)
        {
            LOG(FATA, "epoll create error");
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(DEBUG, "epoll create success, epfd: %d", _epfd);
    }

    bool addFdAndEvent(int fd, uint32_t event)
    {
        int ret = handlerFdEvent(fd, event, EPOLL_CTL_ADD);
        if (!ret)
            LOG(WORING, "addFdAndEvent error, fd: %d", fd);

        LOG(INFO, "addFdAndEvent success, fd: %d", fd);
        return ret;
    }

    bool changeFdEvent(int fd, uint32_t event)
    {
        int ret = handlerFdEvent(fd, event, EPOLL_CTL_MOD);
        if (!ret)
            LOG(WORING, "changeFdEvent error, fd: %d", fd);

        LOG(INFO, "changeFdEvent success, fd: %d", fd);
        return ret;
    }

    bool delFdEvent(int fd)
    {
        int ret = handlerFdEvent(fd, 0, EPOLL_CTL_DEL);
        if (!ret)
            LOG(WORING, "delFdEvent error, fd: %d", fd);

        LOG(INFO, "delFdEvent success, fd: %d", fd);
        return ret;
    }

    int wait(epoll_event *events, int maxevents, int timeout)
    {
        int n = epoll_wait(_epfd, events, maxevents, timeout);
        if (n < 0)
        {
            LOG(FATA, "epoll wait error");
            exit(EPOLL_WAIT_ERROR);
        }
        return n;
    }
    ~epoller()
    {
        if (_epfd >= 0)
            ::close(_epfd);
    }

private:
    int _epfd;
};